<script setup lang="ts">
import type { FormInstance } from 'ant-design-vue'
import { reactive, onMounted, ref } from 'vue'
import { message } from 'ant-design-vue'
import { useUserStore } from '@/stores/user'
import { loginRules } from './hooks/validate'
import { sendUserLoginSms } from '@/api/access'

const emits = defineEmits(['ok'])

// 用户存储
const userStore = useUserStore()

// 状态参数
const state = reactive({
  // 验证码重试倒计时
  smsRetryTimes: 0,
  // 验证码发送状态
  isSmsSending: false,
  // 提交状态
  isSubmit: false,
})

// 表单参数
const formData = ref<LoginForm>({
  loginType: 'phone',
  passport: '',
  password: '',
  phone: '',
  code: '',
})

// 定义组件
const formRef = ref<FormInstance>()

// 发送验证码
const sendSmsCode = () => {
  if (state.smsRetryTimes > 0) {
    return
  }
  formRef.value
    .validateFields(['phone'])
    .then(async () => {
      state.isSmsSending = true
      try {
        state.smsRetryTimes = 60
        const timer = setInterval(() => {
          if (state.smsRetryTimes > 0) {
            state.smsRetryTimes--
          } else {
            clearInterval(timer)
          }
        }, 1000)
        await sendUserLoginSms({
          phone: formData.value.phone,
        })
        message.success('验证码已发送')
      } catch (e) {
        message.error(e.message)
      } finally {
        state.isSmsSending = false
      }
    })
    .catch(() => {})
}

// 登录
const handleLogin = () => {
  formRef.value
    .validate()
    .then(async () => {
      try {
        state.isSubmit = true
        if (formData.value.loginType === 'phone') {
          // 手机登录
          await userStore.loginByPhone(formData.value.phone, formData.value.code)
        } else {
          // 账号登录
          await userStore.loginByAccount(formData.value.passport, formData.value.password)
        }
        // 登录成功回调
        emits('ok', formData.value)
      } catch (e) {
        message.error(e.message)
      } finally {
        state.isSmsSending = false
      }
    })
    .catch(() => {
      message.error('请按提示完善内容')
    })
}

onMounted(() => {
  state.isSubmit = false
})
</script>

<template>
  <a-form ref="formRef" :model="formData" :rules="loginRules" layout="vertical">
    <a-tabs v-model:activeKey="formData.loginType" class="login-tabs">
      <a-tab-pane key="phone" tab="手机登录">
        <template v-if="formData.loginType === 'phone'">
          <a-form-item label="手机号" name="phone">
            <a-input
              v-model:value="formData.phone"
              prefix="+86"
              placeholder="请输入您的手机号"
              autocomplete="false"
            ></a-input>
          </a-form-item>
          <a-form-item label="验证码" name="code">
            <div class="code">
              <a-input
                v-model:value="formData.code"
                placeholder="请输入验证码"
                autocomplete="false"
              ></a-input>
              <a-button
                class="w-[100px]"
                type="default"
                :disabled="state.smsRetryTimes > 0"
                @click="sendSmsCode"
              >
                {{ state.smsRetryTimes > 0 ? state.smsRetryTimes + '秒后重试' : '发送验证码' }}
              </a-button>
            </div>
          </a-form-item>
        </template>
      </a-tab-pane>
      <a-tab-pane key="account" tab="密码登录">
        <template v-if="formData.loginType === 'account'">
          <a-form-item label="账号" name="passport">
            <a-input
              v-model:value="formData.passport"
              placeholder="请输入您的登录账号"
              autocomplete="false"
            ></a-input>
          </a-form-item>
          <a-form-item label="密码" name="password">
            <a-input-password
              v-model:value="formData.password"
              placeholder="请输入您的登录密码"
              autocomplete="false"
            ></a-input-password>
          </a-form-item>
        </template>
      </a-tab-pane>
    </a-tabs>
    <a-form-item>
      <a-button type="primary" size="large" :loading="state.isSubmit" block @click="handleLogin">
        登录
      </a-button>
    </a-form-item>
  </a-form>
</template>

<style lang="scss" scoped>
.login-tabs {
  margin-bottom: 20px;

  .code {
    display: flex;

    .ant-btn {
      margin-left: 15px;
    }
  }

  :deep(.ant-tabs-tabpane) {
    margin-top: 15px;
  }
}
</style>
